<?php
/**
 * erp近30天销量报表 (erp)
 */
namespace App\Logic\SalesReport;

use App\Models\Basics\SysICountry;
use App\Models\Basics\SysPlat;
use App\Models\Basics\SysPlatCountry;
use App\Models\Inventory\AreaCn;
use App\Models\OverSeasBa\DropshippingInventoryFnsku;
use App\Models\OverSeasBa\Warehouse;
use App\Models\OverSeasBa\InventoryBoxFNSku;
use App\Models\OverSeasBa\RemovaleInventoryFNSku;
use App\Models\Product\ProductAmazonSku;
use App\Models\Product\ProductAmazonSkuCCS;
use App\Models\Product\ProductRakutenSku;
use App\Models\Product\ProductRakutenSkuCCS;
use App\Models\Product\ProductShopifySku;
use App\Models\Product\ProductSku;
use App\Models\SalesReport\DailySv;
use App\Models\SalesAmazon\SalesVolumeDay;
use App\Models\SalesReport\FBAInventory;
use Illuminate\Support\Facades\DB;

class DailySalesVolume
{
    /**
     * erp日销量统计报表(近30天)
     */
    public static function init(){

        $amazonPlat = SysPlat::PLAT_AMAZON;
        $shopifyPlat = SysPlat::PLAT_SHOPIFY;
        $rakutenPlat = SysPlat::PLAT_RAKUTEN;

        $start = date('Ymd',strtotime('-30 days'));
        $end = date('Ymd',strtotime('-1 days'));
        $greaterThan = date('Y-m-d');
        DailySv::query()->truncate(); //重置sku销量数据（近30天的数据）

        //amazon产品
        $area = [];
        $inventory = [];
        $sku = [];
        $seller = [];
        ProductAmazonSku::query()
            ->select('country_id','psku_id')
            ->distinct()
            ->chunk(100, function ($items) use ($start,$end,$greaterThan,&$area,&$sku,&$inventory,&$seller,$amazonPlat){
                $dailySvTotals = [];
                foreach($items as $item){
                    $count = DailySv::query()
                        ->where('plat_id',$amazonPlat)
                        ->where('country_id',$item->country_id)
                        ->where('psku_id',$item->psku_id)
                        ->count();
                    if($count > 0)continue;

                    $dailySvTotal = [];
                    $dailySvTotal['plat_id'] = $amazonPlat;
                    $dailySvTotal['country_id'] = $item->country_id;
                    $dailySvTotal['psku_id'] = $item->psku_id;
                    if(!array_key_exists($item->psku_id,$sku)){
                        $_classifyId = ProductSku::getValueById($item->psku_id,'classify_id');
                        $sku[$item->psku_id] = $_classifyId ?: 0;
                    }
                    $classifyId = $sku[$item->psku_id];
                    $dailySvTotal['classify_id'] = $classifyId;
                    if(!array_key_exists($item->country_id,$area)){
                        $area[$item->country_id] = SysICountry::getAreaIdByCountryId($item->country_id);
                    }
                    $areaId = $area[$item->country_id];
                    $dailySvTotal['area_id'] = $areaId;
                    $sellerKey = $item->country_id.'_'.$classifyId;
                    if(!array_key_exists($sellerKey,$seller)){
                        $area[$sellerKey] = ProductAmazonSkuCCS::getSellerId($item->country_id,$classifyId);
                    }
                    $dailySvTotal['seller_id'] = $area[$sellerKey];
                    $inventoryValue = $areaId.'_'.$item->psku_id;
                    if(in_array($inventoryValue,$inventory)){
                        $dailySvTotal['cn_instant_num'] = 0;
                        $dailySvTotal['cn_transit_num'] = 0;
                        $dailySvTotal['os_instant_num'] = 0;
                        $dailySvTotal['os_transit_num'] = 0;
                    }else{
                        $inventory[] = $inventoryValue;
                        $dailySvTotal['cn_instant_num'] = AreaCn::getInstant($areaId,$item->psku_id);
                        $dailySvTotal['cn_transit_num'] = AreaCn::getTransit($areaId,$item->psku_id);

                        $warehouseIds = Warehouse::getIdsByAreaId($areaId);
                        $osInventory1 = InventoryBoxFNSku::getInstantAndTransit($warehouseIds,$item->psku_id,$amazonPlat);
                        $osInventory2 = RemovaleInventoryFNSku::getInstantAndTransit($warehouseIds,$item->psku_id,$amazonPlat);
                        $osInventory3 = DropshippingInventoryFnsku::getInstantAndTransit($warehouseIds,$item->psku_id,$amazonPlat);
                        $dailySvTotal['os_instant_num'] = ($osInventory1->instant ?? 0) + ($osInventory2->instant ?? 0) + ($osInventory3->instant ?? 0);
                        $dailySvTotal['os_transit_num'] = ($osInventory1->transit ?? 0) + ($osInventory2->transit ?? 0) + ($osInventory3->transit ?? 0);
                    }
                    $fbaInventory = FBAInventory::_getInventoryFind($item->country_id,$item->psku_id);
                    if($fbaInventory){
                        $fbaInstant = $fbaInventory->quantity ?: 0;
                        $fbaTransit = $fbaInventory->inbound ?: 0;
                    }else{
                        $fbaInstant = 0;
                        $fbaTransit = 0;
                    }
                    $dailySvTotal['fba_instant_num'] = $fbaInstant;
                    $dailySvTotal['fba_transit_num'] = $fbaTransit;
                    $dailySvTotal['less_than'] = DailySv::SATE_REPORT_DATE;
                    $dailySvTotal['greater_than'] = $greaterThan;

                    //平均销量（平台）
                    $salesVolumeDay = SalesVolumeDay::query()
                        ->where('plat_id', $amazonPlat)
                        ->where('country_id',$item->country_id)
                        ->where('psku_id',$item->psku_id)
                        ->whereBetween('day',[$start,$end])
                        ->select('day',DB::raw('sum(volume) as volume'))
                        ->groupBy('day')
                        ->pluck('volume','day')
                        ->toArray();
                    $avgSalesVolume = self::getAvgSalesVolume($salesVolumeDay);
                    $dailySvTotal = array_merge($dailySvTotal,$avgSalesVolume);
                    $dailySvTotals[] = $dailySvTotal;
                }

                if(!empty($dailySvTotals)){
                    //DB::beginTransaction();
                    //try{
                        DailySv::query()->insert($dailySvTotals);
                    //    DB::commit();
                    //}catch (\Exception $e){
                    //    DB::rollBack();
                    //    report($e);
                    //}
                }
            });
        sleep(2);

        //shopify产品
        $shopifyArea = [];
        $shopifyInventory = [];
        $shopifySku = [];
        $shopifySeller = [];
        ProductShopifySku::query()
            ->select('country_id','psku_id')
            ->distinct()
            ->chunk(100, function ($items) use ($start,$end,$greaterThan,&$shopifyArea,&$shopifySku,&$shopifyInventory,&$shopifySeller,$shopifyPlat){
                $dailySvTotals = [];
                foreach($items as $item){
                    $count = DailySv::query()
                        ->where('plat_id',$shopifyPlat)
                        ->where('country_id',$item->country_id)
                        ->where('psku_id',$item->psku_id)
                        ->count();
                    if($count > 0)continue;

                    $dailySvTotal = [];
                    $dailySvTotal['plat_id'] = $shopifyPlat;
                    $dailySvTotal['country_id'] = $item->country_id;
                    $dailySvTotal['psku_id'] = $item->psku_id;
                    if(!array_key_exists($item->psku_id,$shopifySku)){
                        $_classifyId = ProductSku::getValueById($item->psku_id,'classify_id');
                        $shopifySku[$item->psku_id] = $_classifyId ?: 0;
                    }
                    $classifyId = $shopifySku[$item->psku_id];
                    $dailySvTotal['classify_id'] = $classifyId;
                    if(!array_key_exists($item->country_id,$shopifyArea)){
                        $shopifyArea[$item->country_id] = SysICountry::getAreaIdByCountryId($item->country_id);
                    }
                    $areaId = $shopifyArea[$item->country_id];
                    $dailySvTotal['area_id'] = $areaId;
                    $sellerKey = $item->country_id.'_'.$classifyId;
                    if(!array_key_exists($sellerKey,$shopifySeller)){
                        //$shopifyArea[$sellerKey] = ProductShopifySkuCCS::getSellerId($item->country_id,$classifyId);
                        $shopifyArea[$sellerKey] = 33;
                    }
                    $dailySvTotal['seller_id'] = $shopifyArea[$sellerKey];
                    $inventoryValue = $areaId.'_'.$item->psku_id;
                    if(in_array($inventoryValue,$shopifyInventory)){
                        $dailySvTotal['cn_instant_num'] = 0;
                        $dailySvTotal['cn_transit_num'] = 0;
                        $dailySvTotal['os_instant_num'] = 0;
                        $dailySvTotal['os_transit_num'] = 0;
                    }else{
                        $shopifyInventory[] = $inventoryValue;
                        //$dailySvTotal['cn_instant_num'] = AreaCn::getInstant($areaId,$item->psku_id);
                        //$dailySvTotal['cn_transit_num'] = AreaCn::getTransit($areaId,$item->psku_id);
                        $dailySvTotal['cn_instant_num'] = 0;
                        $dailySvTotal['cn_transit_num'] = 0;

                        $warehouseIds = Warehouse::getIdsByAreaId($areaId);
                        $osInventory1 = InventoryBoxFNSku::getInstantAndTransit($warehouseIds,$item->psku_id,$shopifyPlat);
                        $osInventory2 = RemovaleInventoryFNSku::getInstantAndTransit($warehouseIds,$item->psku_id,$shopifyPlat);
                        $osInventory3 = DropshippingInventoryFnsku::getInstantAndTransit($warehouseIds,$item->psku_id,$shopifyPlat);
                        $dailySvTotal['os_instant_num'] = ($osInventory1->instant ?? 0) + ($osInventory2->instant ?? 0) + ($osInventory3->instant ?? 0);
                        $dailySvTotal['os_transit_num'] = ($osInventory1->transit ?? 0) + ($osInventory2->transit ?? 0) + ($osInventory3->transit ?? 0);
                    }
                    //$fbaInventory = FBAInventory::_getInventoryFind($item->country_id,$item->psku_id);
                    //if($fbaInventory){
                    //    $fbaInstant = $fbaInventory->quantity ?: 0;
                    //    $fbaTransit = $fbaInventory->inbound ?: 0;
                    //}else{
                    //    $fbaInstant = 0;
                    //    $fbaTransit = 0;
                    //}
                    //$dailySvTotal['fba_instant_num'] = $fbaInstant;
                    //$dailySvTotal['fba_transit_num'] = $fbaTransit;

                    $dailySvTotal['less_than'] = DailySv::SATE_REPORT_DATE;
                    $dailySvTotal['greater_than'] = $greaterThan;

                    //平均销量（平台）
                    $salesVolumeDay = SalesVolumeDay::query()
                        ->where('plat_id', $shopifyPlat)
                        ->where('country_id',$item->country_id)
                        ->where('psku_id',$item->psku_id)
                        ->whereBetween('day',[$start,$end])
                        ->select('day',DB::raw('sum(volume) as volume'))
                        ->groupBy('day')
                        ->pluck('volume','day')
                        ->toArray();
                    $avgSalesVolume = self::getAvgSalesVolume($salesVolumeDay);
                    $dailySvTotal = array_merge($dailySvTotal,$avgSalesVolume);
                    $dailySvTotals[] = $dailySvTotal;
                }

                if(!empty($dailySvTotals)){
                    //DB::beginTransaction();
                    //try{
                        DailySv::query()->insert($dailySvTotals);
                    //    DB::commit();
                    //}catch (\Exception $e){
                    //    DB::rollBack();
                    //    report($e);
                    //}
                }
            });
        sleep(2);

        //rakuten产品
        $areaArr = [];
        $inventoryArr = [];
        $skuArr = [];
        $sellerArr = [];
        ProductRakutenSku::query()
            ->select('country_id','psku_id')
            ->distinct()
            ->chunk(100, function ($items) use ($start,$end,$greaterThan,&$areaArr,&$skuArr,&$inventoryArr,&$sellerArr,$rakutenPlat){
                $dailySvTotals = [];
                foreach($items as $item){
                    $count = DailySv::query()
                        ->where('plat_id',$rakutenPlat)
                        ->where('country_id',$item->country_id)
                        ->where('psku_id',$item->psku_id)
                        ->count();
                    if($count > 0)continue;

                    $dailySvTotal = [];
                    $dailySvTotal['plat_id'] = $rakutenPlat;
                    $dailySvTotal['country_id'] = $item->country_id;
                    $dailySvTotal['psku_id'] = $item->psku_id;
                    if(!array_key_exists($item->psku_id,$skuArr)){
                        $_classifyId = ProductSku::getValueById($item->psku_id,'classify_id');
                        $skuArr[$item->psku_id] = $_classifyId ?: 0;
                    }
                    $classifyId = $skuArr[$item->psku_id];
                    $dailySvTotal['classify_id'] = $classifyId;
                    if(!array_key_exists($item->country_id,$areaArr)){
                        $areaArr[$item->country_id] = SysICountry::getAreaIdByCountryId($item->country_id);
                    }
                    $areaId = $areaArr[$item->country_id];
                    $dailySvTotal['area_id'] = $areaId;
                    $sellerKey = $item->country_id.'_'.$classifyId;
                    if(!array_key_exists($sellerKey,$sellerArr)){
                        $areaArr[$sellerKey] = ProductRakutenSkuCCS::getSellerId($item->country_id,$classifyId);
                    }
                    $dailySvTotal['seller_id'] = $areaArr[$sellerKey];
                    $inventoryValue = $areaId.'_'.$item->psku_id;
                    if(in_array($inventoryValue,$inventoryArr)){
                        $dailySvTotal['cn_instant_num'] = 0;
                        $dailySvTotal['cn_transit_num'] = 0;
                        $dailySvTotal['os_instant_num'] = 0;
                        $dailySvTotal['os_transit_num'] = 0;
                    }else{
                        $inventoryArr[] = $inventoryValue;
                        //$dailySvTotal['cn_instant_num'] = AreaCn::getInstant($areaId,$item->psku_id);
                        //$dailySvTotal['cn_transit_num'] = AreaCn::getTransit($areaId,$item->psku_id);
                        $dailySvTotal['cn_instant_num'] = 0;
                        $dailySvTotal['cn_transit_num'] = 0;

                        $warehouseIds = Warehouse::getIdsByAreaId($areaId);
                        $osInventory1 = InventoryBoxFNSku::getInstantAndTransit($warehouseIds,$item->psku_id,$rakutenPlat);
                        $osInventory2 = RemovaleInventoryFNSku::getInstantAndTransit($warehouseIds,$item->psku_id,$rakutenPlat);
                        $osInventory3 = DropshippingInventoryFnsku::getInstantAndTransit($warehouseIds,$item->psku_id,$rakutenPlat);
                        $dailySvTotal['os_instant_num'] = ($osInventory1->instant ?? 0) + ($osInventory2->instant ?? 0) + ($osInventory3->instant ?? 0);
                        $dailySvTotal['os_transit_num'] = ($osInventory1->transit ?? 0) + ($osInventory2->transit ?? 0) + ($osInventory3->transit ?? 0);
                    }
                    //$fbaInventory = FBAInventory::_getInventoryFind($item->country_id,$item->psku_id);
                    //if($fbaInventory){
                    //    $fbaInstant = $fbaInventory->quantity ?: 0;
                    //    $fbaTransit = $fbaInventory->inbound ?: 0;
                    //}else{
                    //    $fbaInstant = 0;
                    //    $fbaTransit = 0;
                    //}
                    //$dailySvTotal['fba_instant_num'] = $fbaInstant;
                    //$dailySvTotal['fba_transit_num'] = $fbaTransit;

                    $dailySvTotal['less_than'] = DailySv::SATE_REPORT_DATE;
                    $dailySvTotal['greater_than'] = $greaterThan;

                    //平均销量（平台）
                    $salesVolumeDay = SalesVolumeDay::query()
                        ->where('plat_id', $rakutenPlat)
                        ->where('country_id',$item->country_id)
                        ->where('psku_id',$item->psku_id)
                        ->whereBetween('day',[$start,$end])
                        ->select('day',DB::raw('sum(volume) as volume'))
                        ->groupBy('day')
                        ->pluck('volume','day')
                        ->toArray();
                    $avgSalesVolume = self::getAvgSalesVolume($salesVolumeDay);
                    $dailySvTotal = array_merge($dailySvTotal,$avgSalesVolume);
                    $dailySvTotals[] = $dailySvTotal;
                }

                if(!empty($dailySvTotals)){
                    //DB::beginTransaction();
                    //try{
                        DailySv::query()->insert($dailySvTotals);
                    //    DB::commit();
                    //}catch (\Exception $e){
                    //    DB::rollBack();
                    //    report($e);
                    //}
                }
            });
        sleep(2);
    }

    /**
     * 平均销量
     * @param $item
     * @return array
     */
    protected static function getAvgSalesVolume($item){
        $re = [];
        $sum3 = 0;
        $sum7 = 0;
        $sum15 = 0;
        $sum30 = 0;
        $count = 0;
        for($i = 30;$i >= 1;$i--){
            $count++;
            $date = date('Ymd',strtotime("-{$i} days"));
            $volume = array_key_exists($date,$item) ? intval($item[$date]) : 0;
            if($count > 27){
                $sum3 += $volume;
            }
            if($count > 23){
                $sum7 += $volume;
            }
            if($count > 15){
                $sum15 += $volume;
            }
            $sum30 += $volume;
        }
        $re['avg3'] = round($sum3 / 3,2);
        $re['avg7'] = round($sum7 / 7,2);
        $re['avg15'] = round($sum15 / 15,2);
        $re['avg30'] = round($sum30 / 30,2);
        $re['sales_status'] = DailySv::getSalesStatus($re['avg3'],$re['avg7'],$re['avg15'],$re['avg30']);
        $re['avg'] = DailySv::getWeightAvg($re['avg3'],$re['avg7'],$re['avg15'],$re['avg30'],$re['sales_status']);
        return $re;
    }

}
